﻿using System;
using Microsoft.SharePoint;
using Microsoft.SharePoint.WebControls;
using Microsoft.SharePoint.Administration;
using Microsoft.SharePoint.ApplicationPages;
using System.Web.UI.WebControls;
using Winwise.SPWebConfig.Core;
using System.Collections.Generic;
using System.Threading;
using Microsoft.SharePoint.Utilities;
using System.IO;
using System.Xml;

namespace Winwise.SPWebConfig.UI
{
    public partial class ManageWebConfigModif : DialogAdminPageBase
    {
        protected void Page_Load(object sender, EventArgs e)
        {
            GVLogs.Sorting += new GridViewSortEventHandler(GVLogs_Sorting);
            GVErrors.Sorting += new GridViewSortEventHandler(GVErrors_Sorting);


        }

        public void ClickDelete(Object sender, CommandEventArgs e)
        {
            int i = Int32.Parse(e.CommandArgument.ToString());

            SPWebApplication currentItem = this.Selector.CurrentItem;
            WebConfigFileChanges changes = currentItem.GetCustomWebConfigModifications();

            changes.WebModif.RemoveAt(i);
            changes.Update();

            OnContextChange(this, null);

        }

        public void ApplyWebConfigModif(object sender, EventArgs e)
        {
            if (this.Selector.CurrentItem != null)
            {
                SPWebApplication currentItem = this.Selector.CurrentItem;
                var fileChanges = currentItem.GetCustomWebConfigModifications();

                WebModificationsUpgradeType modifType = WebModificationsUpgradeType.Incremential;
                switch (RBModifType.SelectedItem.Text)
                {
                    case "Incremental":
                        modifType = WebModificationsUpgradeType.Incremential;
                        break;
                    case "Full":
                        modifType = WebModificationsUpgradeType.Full;
                        break;
                }


                using (SPLongOperation longOperation = new SPLongOperation(this))
                {
                    longOperation.LeadingHTML = "Applying modification on all servers...";
                    longOperation.TrailingHTML = "Wait until the end of the operation...";

                    longOperation.Begin();

                    currentItem.ApplyCustomWebConfigModifications(modifType);
                    currentItem.WaitUntilEndOfWebConfigModification();

                    longOperation.End(this.Request.Url.OriginalString);
                }

            }
        }

        private List<ViewLog> AllLogs = new List<ViewLog>();
        private List<ViewLog> AllErrors = new List<ViewLog>();
        private List<WebConfigModification> Modifs = null;
        private List<ViewAddWebModif> AddWebModif = new List<ViewAddWebModif>();
        bool Populated = false;

        private void PopulateLogsErrors()
        {
            if (Populated)
            {
                return;
            }
            Populated = true;
            AllLogs.Clear();
            AllErrors.Clear();
            SPWebApplication currentItem = this.Selector.CurrentItem;
            foreach (SPServer server in SPFarm.Local.Servers)
            {
                foreach (var iisSettings in currentItem.IisSettings)
                {
                    var zone = iisSettings.Key;
                    string changesName = WebConfigFileChanges.GenerateNameByServerAndZone(server.Id, zone);
                    WebConfigFileChanges localChanges =
                         (SPFarm.Local.GetObject(changesName, currentItem.Id, typeof(WebConfigFileChanges))) as WebConfigFileChanges;
                    if (localChanges != null)
                    {
                        foreach (var item in localChanges.Logs)
                        {
                            AllLogs.Add(new ViewLog()
                            {
                                Date = DateTime.Parse(item.DateTime),
                                Server = server,
                                Zone = zone,
                                Message = item.Message

                            });
                        }

                        foreach (var item in localChanges.Errors)
                        {
                            AllErrors.Add(new ViewLog()
                            {
                                Date = DateTime.Parse(item.DateTime),
                                Server = server,
                                Zone = zone,
                                Message = item.Message

                            });
                        }
                    }
                }
            }

        }

        public void OnContextChange(object sender, EventArgs e)
        {
            if (this.Selector.CurrentItem != null)
            {
                SPWebApplication currentItem = this.Selector.CurrentItem;

                WebConfigFileChanges changes = currentItem.GetCustomWebConfigModifications();
                Modifs = changes.WebModif;

                GVModifs.DataSource = Modifs;
                GVModifs.RowDataBound += new GridViewRowEventHandler(GVModifs_RowDataBound);
                GVModifs.DataBind();


                PopulateLogsErrors();

                GVLogs.DataSource = AllLogs;
                GVLogs.DataBind();
                GVLogs_Sorting(this, new GridViewSortEventArgs("Date", SortDirection.Descending));

                GVErrors.DataSource = AllErrors;
                GVErrors.DataBind();

                string folderFullPath = SPUtility.GetGenericSetupPath("TEMPLATE\\XML\\Winwise.SPWebConfig");
                foreach (string fileName in Directory.GetFiles(folderFullPath))
                {
                    if (!fileName.EndsWith(".xml", StringComparison.InvariantCultureIgnoreCase))
                    {
                        continue;
                    }
                    string fileFullPath = Path.Combine(folderFullPath, fileName);

                    try
                    {
                        using (TextReader reader = File.OpenText(fileFullPath))
                        {
                            using (XmlReader xr = XmlReader.Create(reader))
                            {
                                XmlDocument doc = new XmlDocument();
                                doc.Load(xr);
                                XmlNode node = doc.SelectSingleNode("WebConfigModification");
                                AddWebModif.Add(new ViewAddWebModif()
                                {
                                    AdminUrl =   String.Format("/_admin/{0}?WebApplicationId={1}",  node.Attributes["AdminUrl"].Value,Request.QueryString["WebApplicationId"]),
                                    Name = node.Attributes["Name"].Value,
                                    Description = node.Attributes["Description"].Value,
                                });

                            }
                        }
                    }
                    catch (Exception ex)
                    {
                        LabelErrorMessage.Text = string.Format("Error loading {0} : {1}",fileFullPath, ex.ToString() );
                    }
                }

                RepeaterAdd.DataSource = AddWebModif;
                RepeaterAdd.DataBind();

            }
        }

        void GVModifs_RowDataBound(object sender, GridViewRowEventArgs e)
        {
            if (e.Row.RowType == DataControlRowType.DataRow)
            {
                WebConfigModification webmodif = e.Row.DataItem as WebConfigModification;
                if (((WebConfigModification)(e.Row.DataItem)).SupportEditing)
                {
                    e.Row.FindControl("LblNotSupported").Visible = false;
                    ((HyperLink)e.Row.FindControl("LinkAddEdit")).NavigateUrl =
                        String.Format("/_admin/{0}?WebApplicationId={1}&ModifId={2}", webmodif.AdminPage, Request.QueryString["WebApplicationId"], webmodif.ID);

                }
                else
                {
                    e.Row.FindControl("LblNotSupported").Visible = true;
                    e.Row.FindControl("LinkAddEdit").Visible = false;
                }

                Label lblZones = e.Row.FindControl("LblZone") as Label;
                if (webmodif.Zones.Count == 5)
                {
                    lblZones.Text = "All";
                }
                else
                {
                    foreach (var item in webmodif.Zones)
                    {
                        lblZones.Text += item.ToString() + " ";
                    }
                }
            }
        }



        private void SortGV(SPGridView gv, List<ViewLog> data, GridViewSortEventArgs e, string prefix)
        {
            PopulateLogsErrors();

            string ws = "_" + prefix + e.SortExpression + "_";

            String sortDirection = ViewState[ws] as string;
            if (sortDirection == null)
            {
                sortDirection = "ASC";
            }

            data.Sort(new Comparison<ViewLog>(delegate(ViewLog left, ViewLog right)
            {
                if (e.SortExpression == "Date")
                {
                    int result = -left.Date.CompareTo(right.Date);
                    return sortDirection == "ASC" ? result : -result;
                }
                if (e.SortExpression == "Server")
                {
                    int result = left.Server.DisplayName.CompareTo(right.Server.DisplayName);
                    return sortDirection == "ASC" ? result : -result;
                }
                if (e.SortExpression == "Zone")
                {
                    int result = left.Zone.CompareTo(right.Zone);
                    return sortDirection == "ASC" ? result : -result;
                }
                if (e.SortExpression == "Message")
                {
                    int result = left.Message.CompareTo(right.Message);
                    return sortDirection == "ASC" ? result : -result;
                }
                return 0;
            }));
            gv.DataSource = data;
            gv.DataBind();

            if (sortDirection == "ASC")
            {
                sortDirection = "DSC";
            }
            else
            {
                sortDirection = "ASC";
            }
            ViewState[ws] = sortDirection;
        }

        void GVLogs_Sorting(object sender, GridViewSortEventArgs e)
        {
            SortGV(GVLogs, AllLogs, e, "logs");
        }


        void GVErrors_Sorting(object sender, GridViewSortEventArgs e)
        {
            SortGV(GVErrors, AllErrors, e, "errors");

        }

        public void ClearErrors(object sender, EventArgs e)
        {
            SPWebApplication currentItem = this.Selector.CurrentItem;
            foreach (SPServer server in SPFarm.Local.Servers)
            {
                foreach (var iisSettings in currentItem.IisSettings)
                {
                    var zone = iisSettings.Key;
                    string changesName = WebConfigFileChanges.GenerateNameByServerAndZone(server.Id, zone);
                    WebConfigFileChanges localChanges =
                         (SPFarm.Local.GetObject(changesName, currentItem.Id, typeof(WebConfigFileChanges))) as WebConfigFileChanges;
                    if (localChanges.Errors.Count > 0)
                    {
                        localChanges.Errors.Clear();
                        localChanges.Update();
                    }

                }
            }

            OnContextChange(this, null);
        }


        public void ClearLogs(object sender, EventArgs e)
        {
            SPWebApplication currentItem = this.Selector.CurrentItem;
            foreach (SPServer server in SPFarm.Local.Servers)
            {
                foreach (var iisSettings in currentItem.IisSettings)
                {
                    var zone = iisSettings.Key;
                    string changesName = WebConfigFileChanges.GenerateNameByServerAndZone(server.Id, zone);
                    WebConfigFileChanges localChanges =
                         (SPFarm.Local.GetObject(changesName, currentItem.Id, typeof(WebConfigFileChanges))) as WebConfigFileChanges;
                    if (localChanges.Logs.Count > 0)
                    {
                        localChanges.Logs.Clear();
                        localChanges.Update();
                    }

                }
            }

            OnContextChange(this, null);
        }
    }

    public class ViewLog
    {
        public SPServer Server { get; set; }
        public SPUrlZone Zone { get; set; }
        public DateTime Date { get; set; }
        public string Message { get; set; }

    }

    public class ViewModif
    {
        public string DisplayName { get; set; }
        public string TypeName { get; set; }
    }

    public class ViewAddWebModif
    {
        public string Name { get; set; }
        public string AdminUrl { get; set; }
        public string Description { get; set; }
    }
}
